#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>

//asdafsdfsd
int main(int argc, char** argv){
    //tempo inicio
    struct timeval tv;
    double curtime, totaltime;
    gettimeofday(&tv,NULL);
    curtime= tv.tv_sec+ tv.tv_usec/1e6;
    //

    if (argc < 5){
        printf("./cliente host_do_servidor porto_servidor nome_arquivo tam_buffer\n");
        exit(1);
    }

    struct in_addr serv_host;
    serv_host.s_addr = inet_addr(argv[1]);

    unsigned short int serv_port;
    serv_port = htons(atoi(argv[2]));

    char *fileName;
    fileName = argv[3];


    int buffer_size = atoi(argv[4]);

    int sock;
    struct sockaddr_in serv_sock;

    //inicializacao do socket e checagem de erro
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0){
        perror("socket");
        exit(1);
    }
        
    serv_sock.sin_family = AF_INET;
    serv_sock.sin_port = serv_port;
    serv_sock.sin_addr.s_addr = serv_host.s_addr;
    
    bzero(&(serv_sock.sin_zero), 8);

    //estabelece conexão 
    if (connect(sock, (struct sockaddr *) &serv_sock, sizeof(struct sockaddr)) < 0){
        perror("connect");
        exit(1);
    }
    printf("Conexão: %s\n", inet_ntoa(serv_sock.sin_addr));

    //envia nome do arquivo
    int fileNameSize = strlen(fileName) + 1;
    if (send(sock, fileName, fileNameSize, 0) < 0){
        perror("send");
        exit(1);
    }

    //abre o arquivo
    FILE *fileIn;
    if( (fileIn = fopen(fileName,"w+")) == NULL ){
        close(sock);
        close(fileIn);
        perror("fopen");
        exit(1);
    }
    printf("File Open: %s\n", fileName);
    //

    //recebendo arquivo
    unsigned int received = 0;
    char* buffer;
    buffer = (char*)malloc(sizeof(char)*buffer_size);

    int bytes = 0;
    while((bytes = recv(sock, buffer, buffer_size, 0)) > 0){
        //escreve no arquivo
        received += fwrite(buffer, 1, bytes, fileIn);
    }

    fclose(fileIn);
    close(sock);

    //tempo fim
    double endtime;
    gettimeofday(&tv,NULL);
    endtime= tv.tv_sec+ tv.tv_usec/1e6;
    totaltime= (endtime - curtime);
    //

    printf("Buffer = \%5u byte(s), \%.3f kbps (\%u bytes em \%.6f s)\n", buffer_size, (received / totaltime), received, totaltime);
//    printf("\%5u \%.2f \%u\n", buffer_size, (received / totaltime), received);
    printf("\%.2f\n", (received / totaltime));
    exit(0);
}
